using System.Diagnostics.CodeAnalysis;

namespace UnitTesting.Fixturing
{
	class DefaultFixtureParams
	{
		internal virtual IValueProvider ValueProvider { get; set; }

		internal virtual ISimpleTypeStrategy SimpleTypeStrategy { get; set; }

		internal virtual IValueProviderCustomizable ValueProviderCustomizable { get; set; }

		internal virtual IManyCountSetter ManyCountSetter { get; set; }

		internal virtual IFreezable Freezable { get; set; }

		[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
		internal DefaultFixtureParams(object fixtureOptions)
		{
			var compositeValueProvider = new StaticCompositeValueProvider();

			var freezeValueProvider = new FreezeValueProvider();
			var customValueProvider = new StaticCompositeValueProvider();
			var simpleValueProvider = new SimpleValueProvider();
			var enumValueProvider = new EnumValueProvider(simpleValueProvider);
			var manyValueProvider = new ManyValueProvider(compositeValueProvider);
			var delegateValueProvider = new DelegateValueProvider(compositeValueProvider);
			// ReSharper disable DoNotCallOverridableMethodsInConstructor
			var reflectionValueProvider = CreateReflectionValueProvider(compositeValueProvider, freezeValueProvider,fixtureOptions);
			var privateReflectionValueProvider = CreateReflectionValueProvider(
				compositeValueProvider, freezeValueProvider, fixtureOptions, DefaultActivator.Instance);

			compositeValueProvider.Add(freezeValueProvider,
			                           customValueProvider,
			                           simpleValueProvider,
			                           enumValueProvider,
			                           manyValueProvider,
			                           delegateValueProvider,
			                           reflectionValueProvider,
			                           privateReflectionValueProvider);
			
			SimpleTypeStrategy = simpleValueProvider;
			ValueProviderCustomizable = customValueProvider;
			ManyCountSetter = manyValueProvider;
			Freezable = freezeValueProvider;
			ValueProvider = CreateGuardNotResovledValue(compositeValueProvider);
			// ReSharper restore DoNotCallOverridableMethodsInConstructor
		}

		internal virtual IValueProvider CreateGuardNotResovledValue(IValueProvider valueProvider)
		{
			return new GuardNotResovledValue(valueProvider);
		}

		internal virtual ReflectionValueProvider CreateReflectionValueProvider(
			IValueProvider valueProvider, IFreezable freezable, 
			object fixtureOptions, IActivator activator = null)
		{
			if (activator == null)
				return new ReflectionValueProvider(valueProvider, freezable, fixtureOptions);
			return new ReflectionValueProvider(valueProvider, activator, freezable, fixtureOptions);
		}

		protected DefaultFixtureParams()
		{
		}
	}
}